package cn.miju.alipay.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.miju.alipay.request.AlipayApplyQrCodeReq;
import cn.miju.alipay.response.AlipayApplyQrCodeResp;
import cn.miju.alipay.response.AlipayBaseResp;
import cn.miju.common.content.CodeMessage;
import cn.miju.common.util.ValidationUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * <pre>
 * 申请支付二维码
 * </pre>
 *
 * @author zhuming
 * @version 1.0.0
 * @since 2023-02-28 11:24
 */
@Slf4j
@Component
public class AlipayApplyQrCodeHandler extends AbstractAlipayHandler<AlipayApplyQrCodeReq, AlipayApplyQrCodeResp> {

    /**
     * 请求参数前置处理
     *
     * @param req 请求参数
     * @return 结果
     */
    @Override
    public AlipayTradePrecreateRequest beforeRequest(AlipayApplyQrCodeReq req) {
        ValidationUtil.validate(req);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", req.getOutTradeNo());
        bizContent.put("total_amount", req.getTotalAmount().setScale(2, RoundingMode.HALF_DOWN));
        bizContent.put("subject", req.getTitle());
        bizContent.put("body", req.getDescription());
        if (req.getAlipayProperties().isProdEnv() && null != req.getTimeExpire()) {
            bizContent.put("time_expire", LocalDateTime.now().plusSeconds(req.getTimeExpire()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        super.setOptionalReqParams(bizContent, req.getOptionalReqParams());
        request.setBizContent(bizContent.toString());
        request.setNotifyUrl(req.getNotifyUrl());
        request.setProdCode("FACE_TO_FACE_PAYMENT");
        return request;
    }

    /**
     * 核心执行
     * @param req {@link AlipayApplyQrCodeReq}
     * @return {@link AlipayApplyQrCodeResp}
     */
    @Override
    public AlipayApplyQrCodeResp doPlan(AlipayApplyQrCodeReq req) {
        AlipayTradePrecreateRequest request = this.beforeRequest(req);
        log.info("API--扫码支付--alipay.trade.precreate(统一收单线下交易预创建)-->Request：{}", JSON.toJSONString(request));
        AlipayTradePrecreateResponse response = null;
        AlipayClient alipayClient = super.createAlipayClient(req.getAlipayProperties());
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            AlipayBaseResp baseResp = AlipayBaseResp.builder(CodeMessage.FAIL);
            log.error("API--扫码支付--alipay.trade.precreate(统一收单线下交易预创建)-->Exception：{}", e.getMessage(), e);
            return AlipayApplyQrCodeResp.builder().
                    code(baseResp.getCode()).
                    msg(baseResp.getMsg()).
                    build();
        }
        log.info("API--扫码支付--alipay.trade.precreate(统一收单线下交易预创建)-->Response：{}", JSON.toJSONString(response));
        return this.afterResponse(response);
    }

    /**
     * 响应参数后置处理
     *
     * @param resp 响应参数
     * @return 结果
     */
    @SneakyThrows
    @Override
    public AlipayApplyQrCodeResp afterResponse(AlipayResponse resp) {
        AlipayBaseResp baseResp = AlipayBaseResp.builder(CodeMessage.FAIL);
        AlipayTradePrecreateResponse response = (AlipayTradePrecreateResponse) resp;
        baseResp.setMsg(StringUtils.isEmpty(response.getSubMsg()) ? baseResp.getMsg() : response.getSubMsg());
        if (response.isSuccess()) {
            baseResp = AlipayBaseResp.builder(CodeMessage.SUCCESS);
        }
        if (!StringUtils.isEmpty(response.getSubMsg()) && "ACQ.TRADE_NOT_EXIST".equals(response.getSubMsg())) {
            baseResp = AlipayBaseResp.builder(CodeMessage.TRADE_NOT_EXIT);
        }
        AlipayApplyQrCodeResp applyQrCodeResp = BeanUtil.copyProperties(baseResp, AlipayApplyQrCodeResp.class);
        applyQrCodeResp.setQrcode(response.getQrCode());
        applyQrCodeResp.setOutTradeNo(response.getOutTradeNo());
        return applyQrCodeResp;
    }
}
